package com.allin.http.request;

import android.text.TextUtils;

import com.allin.http.ParamUtil;
import com.allin.http.callback.ResultCallback;
import com.google.gson.GsonBuilder;
import com.squareup.okhttp.FormEncodingBuilder;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;

import java.io.File;
import java.util.Map;

/**
 * desc:put方式提交
 * author： LiangYuanQi
 * date：2015/12/4.
 */
public class OkHttpPutRequest extends OkHttpRequest{

    private String content;  //需要提交的文本内容
    private byte[] bytes;    //需要提交的字节流
    private File file;        //需要提交的文件
    private MediaType mediaType;  //客户端>服务器 内容传输格式

    //参数类型-与内容传输格式一 一对应
    private int type=0;   //默认x-www-form-urlencoded    key=value&key2=value2
    private static final int TYPE_PARAMS = 1;  //默认json    {key:value,key2:value2}
    private static final int TYPE_STRING = 2;
    private static final int TYPE_BYTES = 3;
    private static final int TYPE_FILE = 4;

    //定义几种默认的内容传输格式
    private final MediaType MEDIA_TYPE_STREAM = MediaType.parse("application/octet-stream;charset=utf-8");
    private final MediaType MEDIA_TYPE_STRING = MediaType.parse("text/plain;charset=utf-8");
    private final MediaType MEDIA_TYPE_JSON=MediaType.parse("application/json;charset=utf-8");

    public OkHttpPutRequest(String url, Object tag, Map<String, Object> params, Map<String, String> headers, MediaType mediaType, String content, byte[] bytes, File file){
        super(url, tag, params, headers);
        this.mediaType = mediaType;
        this.content = content;
        this.bytes = bytes;
        this.file = file;
    }

    /**
     * 验证参数类型
     */
    protected void validParams()
    {
        int count = 0;
        if (params != null && !params.isEmpty())
        {
            type = TYPE_PARAMS;
            count++;
        }
        if (content != null)
        {
            type = TYPE_STRING;
            count++;
        }
        if (bytes != null)
        {
            type = TYPE_BYTES;
            count++;
        }
        if (file != null)
        {
            type = TYPE_FILE;
            count++;
        }

        if (count <= 0 || count > 1)
        {
            throw new IllegalArgumentException("the params , content , file , bytes must has one and only one .");
        }
    }

    /**
     * 构建带表单的请求
     * @return
     */
    @Override
    protected Request buildRequest() {
        if(TextUtils.isEmpty(url)){
            throw new IllegalArgumentException("url cannot empty");
        }
        Request.Builder builder = new Request.Builder();
        super.appendHeaders(builder,headers);
        builder.url(url).tag(tag).put(requestBody);
        return builder.build();
    }

    /**
     * 构建参数体
     * map类型的参数采用json的方式向服务器发送数据，
     * 如果不指定参数传递类型，默认采用url encode的方式向服务器发送数据
     * @return
     */
    @Override
    protected RequestBody buildRequestBody() {
        validParams();
        RequestBody rb =null;
        switch (type){
            case TYPE_PARAMS:
                String jsonParam = new GsonBuilder().create().toJson(params);  //把map类型的参数转换为json
                rb=RequestBody.create(mediaType != null ? mediaType : MEDIA_TYPE_JSON, jsonParam);
                break;
            case TYPE_BYTES:
                rb=RequestBody.create(mediaType != null ? mediaType : MEDIA_TYPE_STREAM, bytes);
                break;
            case TYPE_FILE:
                rb=RequestBody.create(mediaType != null ? mediaType : MEDIA_TYPE_STREAM, file);
                break;
            case TYPE_STRING:
                rb=RequestBody.create(mediaType != null ? mediaType : MEDIA_TYPE_STRING, content);
                break;
            default:
                FormEncodingBuilder builder = new FormEncodingBuilder();
                ParamUtil.addParams(builder, params);
                requestBody = builder.build();
                break;
        }
        return rb;
    }

    /**
     * 添加当前网络传输百分比
     * @param rb
     * @param callback
     * @return
     */
    protected RequestBody wrapReqeustBody(RequestBody rb,final ResultCallback callback){
        CountingRequestBody crb=new CountingRequestBody(requestBody,new CountingRequestBody.Listener(){
            @Override
            public void onRequestProgress(final long bytesWritten, final long contentLength) {
                mOkHttpClientManager.getDelivery().post(new Runnable() {
                    @Override
                    public void run() {
                        callback.inProgress(bytesWritten * 1.0f / contentLength);
                    }
                });
            }
        });
        return crb;
    }


}
